package schedule;


import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

import com.google.gdata.client.calendar.CalendarQuery;
import com.google.gdata.client.calendar.CalendarService;
import com.google.gdata.data.Link;
import com.google.gdata.data.batch.BatchOperationType;
import com.google.gdata.data.batch.BatchStatus;
import com.google.gdata.data.batch.BatchUtils;
import com.google.gdata.data.calendar.CalendarEventEntry;
import com.google.gdata.data.calendar.CalendarEventFeed;
import com.google.gdata.util.AuthenticationException;
import com.google.gdata.util.ServiceException;


public class GoogleCalendarExporter
{	
	private final static String DEFAULT_EVENT_FEED_URL = "https://www.google.com/calendar/feeds/default/private/full";
	
	private CalendarService calendarService;
	private URL eventFeedUrl;
	CalendarEventFeed batchRequest;
	
	public GoogleCalendarExporter(String application)
	{
		calendarService = new CalendarService(application);
		batchRequest = new CalendarEventFeed();
		try
		{
			this.eventFeedUrl = new URL(DEFAULT_EVENT_FEED_URL);
		}
		catch(MalformedURLException e)
		{
			e.printStackTrace();
		}
	}
	
	public GoogleCalendarExporter(String application, URL eventFeedUrl)
	{
		calendarService = new CalendarService(application);
		this.eventFeedUrl = eventFeedUrl;
		batchRequest = new CalendarEventFeed();
	}
	
	public void setUserCredentials(String username, String password) throws AuthenticationException
	{
		calendarService.setUserCredentials(username, password);
	}
	
	public void export(Schedule schedule) throws ServiceException, IOException
	{
		try
		{
			batchRequest.getEntries().clear();
			CalendarEventFeed feed = createClearBatchRequest();
			createAddingBatchRequest(schedule);
			
			Link batchLink = feed.getLink(Link.Rel.FEED_BATCH, Link.Type.ATOM);
			CalendarEventFeed batchResponse = calendarService.batch(new URL(batchLink.getHref()), batchRequest);
			
			for(CalendarEventEntry entry : batchResponse.getEntries())
			{
				String batchId = BatchUtils.getBatchId(entry);
				
				if(!BatchUtils.isSuccess(entry))
				{
				    BatchStatus status = BatchUtils.getBatchStatus(entry);
				    System.out.println("\n" + batchId + " failed (" + status.getReason() + ") " + status.getContent());
				}
			}
		}
		catch (MalformedURLException e)
		{
			e.printStackTrace();
		}
	}
	
	private CalendarEventFeed createClearBatchRequest() throws ServiceException, IOException
	{
		CalendarQuery query = new CalendarQuery(eventFeedUrl);
		query.setMaxResults(9999);
		int startIndex = 1;
		query.setStartIndex(startIndex);
		CalendarEventFeed feed = calendarService.query(query, CalendarEventFeed.class);
		
		while(!feed.getEntries().isEmpty())
		{
			for(CalendarEventEntry toDelete : feed.getEntries())
			{
				BatchUtils.setBatchId(toDelete, String.valueOf(batchRequest.getEntries().size()));
				BatchUtils.setBatchOperationType(toDelete, BatchOperationType.DELETE);
				batchRequest.getEntries().add(toDelete);
			}
			
		    startIndex = startIndex + feed.getEntries().size();
		    query.setStartIndex(startIndex);
			feed = calendarService.query(query, CalendarEventFeed.class);
		}
		
		return feed;
	}
	
	private void createAddingBatchRequest(Schedule schedule)
	{
		for(Event event : schedule)
		{
			CalendarEventEntry toInsert = event.toCalendarEventEntry();				
			BatchUtils.setBatchId(toInsert, String.valueOf(batchRequest.getEntries().size()));
			BatchUtils.setBatchOperationType(toInsert, BatchOperationType.INSERT);
			batchRequest.getEntries().add(toInsert);
		}
	}
}
